// App Store Stuff

var wookie_url = "/wookie";
var store_rest_url = "/edukapp/api/rest";
//var wookie_url = "http://wookie.eun.org/wookie";
//var store_rest_url = "http://wookie.eun.org/edukapp/api";
var search_term = "";
var savedResultsTitle;

var tagList;
var popularTags;

var storedPassword;
var isAdmin;
var startupConfiguration;
var startPage;

var gStandardCookieTimeout = 60 * 3000;

var onlineUser;


// ---------------------------------------------------------------------------------
// Inline stuff
// ---------------------------------------------------------------------------------
var basic_scroller_html = "<div class=\"scrollable\" id=\"browsable\">"+
"<div class=\"items\" id=\"items\">" +
"</div>" +
"</div>" +
"<div class=\"navi\"></div>";


var dialogs = '<div id="register-form" title="Register new user" class="dlog-form">'+
	'<p class="validateTips">All form fields are required.</p>'+
	'<form>'+
	'<fieldset>'+
		'<label for="r-username">Username</label>'+
		'<input type="text" name="username" id="r-username" class="text ui-widget-content ui-corner-all" />'+
		'<label for="r-email">Email</label>'+
		'<input type="text" name="email" id="r-email" value="" class="text ui-widget-content ui-corner-all" />'+
		'<label for="r-password">Password</label>'+
		'<input type="password" name="password" id="r-password" value="" class="text ui-widget-content ui-corner-all" />'+
		'<label for="r-realname">Real Name</label>'+
		'<input type="text" name="realname" id="r-realname" class="text ui-widget-content ui-corner-all" />'+
	'</fieldset>'+
	'</form>'+
'</div>'+
'<div id="login-form" title="Login" class="dlog-form">'+
	'<p class="validateTips"></p>'+
	'<form>'+
		'<fieldset>'+
			'<label for="l-username">Username</label>'+
			'<input type="text" name="username" id="l-username" class="text ui-widget-content ui-corner-all"/>'+
			'<label for="l-password">Password</label>'+
			'<input type="password" name="password" id="l-password" class="text ui-widget-content ui-corner-all"/>'+
		'</fieldset>'+
	'</form>'+
'</div>';

var tagsDialog = '<div id="tags-dialog" title="Choose Existing Tag" class="tags-dialog">';
var divEnd = '</div>';


// -----------------------------------------------------------------------------------
// first function to be called when widgetstore is shown
// -----------------------------------------------------------------------------------

/*
function firstLogin ( ) {
	var instanceKey = window.widget.getInstanceKey();
	if ( instanceKey ) {
		setCookie("idKey", instanceKey );
	}
	var proxy = window.widget.getProxyUrl();
	if ( proxy ) {
		setCookie ("proxyUrl", proxy );
	}
	isAdmin = (Widget.preferences.getItem("manager") == "true");
	if ( isAdmin) {
		setCookie("admin", "true" );
	}
	else {
		setCookie("admin", "false");
	}

	var waveViewer = getWaveViewer();
	if (waveViewer == null ) {
		alert("No viewer set");
		removeUser();
		setLogin();
		return;
	}
	var displayName = waveViewer.getDisplayName();
	if ( displayName != "Guest" ) {
		var id = waveViewer.getId();
		var password = "internaltemp";
		loginViaAjax( id, password );
	}
	else {
		removeUser();
		setLogin();
	}
}
*/

function firstLogin ( ) {
	var instanceKey = window.widget.getInstanceKey();
	if ( instanceKey ) {
		setCookie("idKey", instanceKey );
	}
	var proxy = window.widget.getProxyUrl();
	if ( proxy ) {
		setCookie ("proxyUrl", proxy );
	}
	var sConfJSON = Widget.preferences.getItem("startup_configuration");
	
	if ( sConfJSON != null && sConfJSON != "null" ) {
		// we are embedded
		setCookie ( "embedded", "true" );
		startupConfiguration = $.parseJSON(sConfJSON);
		
		startPage = startupConfiguration.start_page;
		if ( startupConfiguration.iwc_call_name) {
			setCookie ("iwc_call_name", startupConfiguration.iwc_call_name );
		}
		setCookie ("workspace_widget_specifier", startupConfiguration.workspace_widget_specifier);
		var lang = "en";
		if ( startupConfiguration.language ) {
			lang = startupConfiguration.language;
		}
		setCookie ("language", lang);
		var roles = startupConfiguration.roles;
		var role = "teacher";
		for ( var i = 0; i < roles.length; i++ ) {
			var aRole = roles[i];
			if ( aRole == "administrator" ) {
				role = aRole;
				break;
			}
		}

		if ( role == "administrator"  ) {
			setCookie("admin", "true" );
		}
		else {
			setCookie("admin", "false");
		}
	}
	else {
		setCookie ( "embedded", "false" );
		isAdmin = (Widget.preferences.getItem("manager") == "true");
		if ( isAdmin ) {
			setCookie("admin", "true" );
		}
		else {
			setCookie("admin", "false" );
		}		
		startPage = null;
	}


	var waveViewer = getWaveViewer();
	if (waveViewer == null ) {
		alert("No viewer set");
		removeUser();
		setLogin();
		return;
	}
	var displayName = waveViewer.getDisplayName();
	if ( displayName != "Guest" ) {
		var id = waveViewer.getId();
		var password = "internaltemp";
		loginViaAjax( id, password );
	}
	else {
		setLogin();
	}
}


// ---------------------------------------------------------------------------------
// Utilities
// ---------------------------------------------------------------------------------

function getQueryVariable(variable) {
    var query = window.location.search.substring(1);
    var vars = query.split("&");
    for (var i = 0; i < vars.length; i++) {
        var pair = vars[i].split("=");
        if (pair[0] == variable) {
            return unescape(pair[1]);
        }
    }
	return null;
}


function nowInSeconds ( ) {
	return Math.round( new Date().getTime()/1000);
}



// ---------------------------------------------------------------------------------
// Widget Search and Listing
// ---------------------------------------------------------------------------------

function selectOrDeselectSideNavigation ( toSelect, navigationId )
{
	if ( toSelect ) {
		$(navigationId).removeClass("widgetFilterItem").addClass("widgetFilterItemSelected");
	}
	else {
		if ($(navigationId).hasClass("widgetFilterItemSelected")) {
			$(navigationId).removeClass("widgetFilterItemSelected").addClass("widgetFilterItem");
		}
	}
}


function changeSelection (selectedID) {
	selectOrDeselectSideNavigation ( selectedID == "#selectFavourites", "#selectFavourites");
	selectOrDeselectSideNavigation ( selectedID == "#selectFeatured", "#selectFeatured");
	selectOrDeselectSideNavigation ( selectedID == "#selectMostRecent", "#selectMostRecent");
	selectOrDeselectSideNavigation ( selectedID == "#selectAll", "#selectAll");
}


function searchStoreWidgets( search ) {
	changeSelection("#selectAll");
	search_term = search;
	$.ajax({
		type:"GET",
		url:store_rest_url+"/widgets/search/"+search+"/0/5000",
		dataType: "text",
		success: parseSearchedWidgets
	});
}


function searchStoreWidgetsOrderby ( search, orderby ) {
	changeSelection("#selectMostRecent");
	search_term = "Ordered By: "+orderby;
	var uri = store_rest_url+'/widgets/search/'+search+'/0/30/'+orderby;
	$.ajax({
		type: "GET",
		url:uri,
		dataType: "text",
		success: parseSearchedWidgets
	});
}
		



function getFeaturedWidgets ( ) {
	changeSelection("#selectFeatured");
	search_term = "Featured Widgets";
	$.ajax({
		type:"GET",
		url:store_rest_url+"/widgets/featured",
		dataType: "text",
		success: parseSpecialWidgets
	});
}

function getMyFavourites() {
	changeSelection("#selectFavourites");
	var u = getUser();
	if ( u == null ) {
		return; // don't do anything - should never be called
	}
	var userId = u.username;
	search_term = "My Favourites";
	$.ajax({
		type:"GET",
		url:store_rest_url+"/users/favourites/"+userId,
		beforeSend: function(xhr) {
			var authString = getBase64Authentication();
			xhr.setRequestHeader("Authorization", "Basic "+authString);
		},
		dataType: "text",
		success: parseFavouriteWidgets
	});
}


/*function searchWidgetsForTag ( tagId ) {
	var uri = store_rest_url + '/tag/' + tagId +'/widgets'
	$.ajax({
		type: "GET",
		url:uri,
		dataType:"text",
		success: parseSearchedWidgets
	});
}*/
	

function parseSpecialWidgets(jsonString) {
	var specialwidgets = [];
	parseAndCopyWidgetList (jsonString, specialwidgets );
	indexSpecialWidgets ( specialwidgets);
}

function parseFavouriteWidgets (jsonString) {
	var favouriteWidgets = [];
	parseAndCopyWidgetList(jsonString, favouriteWidgets);
	indexFavouriteWidgets (favouriteWidgets);
}

function parseSearchedWidgets(jsonString) {
	var searchedwidgets = [];
	parseAndCopyWidgetList ( jsonString, searchedwidgets );
	indexSearchedWidgets(searchedwidgets);
}

function parseFeaturedWidgets ( jsonString ) {
	var featuredwidgets = [];
	parseAndCopyWidgetList ( jsonString, featuredwidgets );
	indexFeaturedWidgets(featuredwidgets);
}


function parseAndCopyWidgetList ( inJSON, outWidgetList ) {
	var obj = $.parseJSON(inJSON);
	var widgets = obj.widgets;
	if ( widgets == null ) {
		// try SearchResults returned by later versions of edukapp
		widgets = obj.SearchResults;
		if ( widgets == null ) {
			// try just getting top level, might just be an array
			widgets = obj;
		}
	}
	if ( $.isArray(widgets)) {
		for ( var i = 0; i < widgets.length; i++ ) {
			var widget = widgets[i];
			if ( widget.deleted == 0 && widget.publish_level == 2 ) {
				if ( widget.icon == null || widget.icon == "" ) {
					widget.icon = "img/default_widget_icon.png";
				}
				outWidgetList.push ( widget );
			}
		}
	}
}

function indexFavouriteWidgets(widgetlist)
{
	$("#items").html("");
	for ( var i = 0; i < widgetlist.length; i++ ) {
		var widget = widgetlist[i];
		var html = buildOneSpecialWidget(widget, i, true);
		$("#items").append(html);
		if ( widget.widgetStats.averageRating > 0 ) {
			$("#average"+i+1).raty({score: widget.widgetStats.averageRating, readOnly:true});
		}
	}
}


function indexSpecialWidgets ( widgets ) {
	buildSpecialWidgetListHTML ( widgets );
	setSearchTerm (  );
	//$(".avgr").raty({score: Math.floor((Math.random()*5)+1), readOnly:true});
}

function indexSearchedWidgets(searchedwidgets){
    buildWidgetListHTML ( searchedwidgets );
    setSearchTerm (  );
}

function setSearchTerm (  ) {
    var search_results_title = "Search Results: ";
    if ( search_term == "*:*") {
    	search_results_title += "All";
    }
    else if ( search_term == "" ) {
    	search_results_title = "Oops, tried to search on nothing!";
    }
    else {
    	search_results_title += search_term;
    }
    $("#results_title").html(search_results_title);
    //$("#top_section").html(basic_scroller_html);
    //$("#items").html(html);
    
    // initialize scrollable together with the navigator plugin
    //u $("#browsable").scrollable().navigator();	
}





function buildWidgetListHTML ( widgetlist ) {
    /*count = 0;
    var html = "";
	for ( var i = 0; i<widgetlist.length; i++ ) {
		var widget = widgetlist[i];
    	if ( count == 0) {
    		html += "<div>";
    	}
    	count++;
    	html += widgetToHTML(widget);
    	if ( count == 6){
    		html += "</div>";
    		count = 0;
    	}
    }
    if ( count > 0 && count < 6 ) {
    	html += "</div>";
    }*/
	$("#items").html("");
	for ( var i = 0; i < widgetlist.length; i++ ) {
		var html = '';
		var widget = widgetlist[i];
		html += '<div class="widget_link" onclick="showWidgetView(\''+widget.id+'\')">';
		html += '<img src="'+widget.icon+'" width="22" height="22" onerror="this.src=\'img/default_widget_icon.png\'">';
		html += '&nbsp;<span class="widget_title">'+widget.name+'</span>';
		html += '</div>';
		$("#items").append(html);
	}
}


function buildSpecialWidgetListHTML( widgetlist ) {
	$("#items").html("");
	for ( var i = 0; i < widgetlist.length; i++ ) {
		var widget = widgetlist[i];
		var html = buildOneSpecialWidget(widget, i, false);
		$("#items").append(html);
		if ( widget.totalRatings > 0 ) {
			$("#average"+i+1).raty({score: widget.averageRating, readOnly:true});
		}
	}
}

function buildOneSpecialWidget ( widget, i, favourite ) {
	var html = '';
	html += '<div class="widgetPlacardBox">';
	html += '<div class="widgetIcon" onclick="showWidgetView(\''+widget.id+'\')"><img src="'+widget.icon+'" width="80" height="80"/></div>';
	html += '<div class="widgetTitle" onclick="showWidgetView(\''+widget.id+'\')">'+widget.name+'</div>';
	var category = '';
	if ( widget.categories != null && widget.categories.length > 0 ) {
		category = widget.categories[0].title;
	}
		
	html += '<div class="widgetCategory">'+category+'</div>';
	if (widget.totalRatings == 0 ) {
		html += '<div class="widgetRating"><span>Not yet rated</span></div>';
	}
	else {
		html += '<div class="widgetRating"><span id="average'+i+1+'"></span>('+widget.totalRatings+')</div>';
	}
	if ( favourite ) {
		html += '<button onClick="removeWidgetFavourite('+widget.id+')" class="removeButton">Remove</button>';
	}
	html += '</div>';
	return html;
}


function widgetToHTML(widget){
    var html = "";
    html += '<div class="item">';
    var iconPath;
    if ( widget.icon == null || widget.icon == "" ) {
    	iconPath = "img/default_widget_icon.png";
    }
    else {
    	iconPath = widget.icon;
    }
    html += '<img src="'+iconPath+'" onclick=\"selectWidget(\''+widget.id+'\')\" />';
    html += '<p>';
    html += '<span class="widgetTitle">'+widget.name+'</span><br/>';
    if ( widget.totalRatings == null ) {
    	widget.totalRatings = 0;
    }
    html +=  '<span class="rating">'+widget.totalRatings+' ratings</span><br/>';
    if ( widget.averageRating == null ) {
    	widget.averageRating = 0;
    }
    html += '<span class="rating">Average Rating: '+widget.averageRating+'</span><br/>';
    html +=  '</p>';
    html +=  '<button onclick=\"showWidgetView(\''+widget.id+'\')\">More Info...</button>';
    html +=  '</div>';
    return html;
}


function getWidgetInfo(widgetid){
	var uri = store_rest_url + "/widgets/"+widgetid;
	
	$.ajax({
		url:uri,
		type:"GET",
		dataType:"text",
		success:parseOneWidget
	});
}


function parseOneWidget(jsonString) {
	var widgetInfo = $.parseJSON(jsonString);
	sendSignal("receivedWidgetInfo", widgetInfo);
}


// ---------------------------------------------------------------------------------
// User Registration and Login
// ---------------------------------------------------------------------------------


function setUser ( userJSON ) {
	onlineUser = $.parseJSON(userJSON);
	var encoded = encodeURIComponent(userJSON);
	setCookie ( "store_user", encoded, 60 * 1000 );
}

function setStoredPassword (pw) {
	var b64pw = Base64.encode(pw);
	setCookie ( "stpw", b64pw, gStandardCookieTimeout );
}

function getStoredPassword ( ){
	var b64pw= getCookie("stpw");
	return Base64.decode(b64pw);
}

function clearStoredPassword() {
	storedPassword = null;
	deleteCookie("stpw");
}


function getBase64Authentication() {
	var u = getUser();
	var p = getStoredPassword();
	return Base64.encode(u.username+":"+p);
}


function getUser ( ) {
	var encodedJSON = getCookie ( "store_user");
	if ( encodedJSON != null ) {
		var userJSON = decodeURIComponent(encodedJSON);
		return $.parseJSON(userJSON);
	}
	else {
		return null;
	}
}



function removeUser ( ) {
	deleteCookie ( "store_user");
}


function getWaveViewer ( ) {
	var waveViewer = wave.getViewer();
	return waveViewer;
}



function isAdmin ( ) {
	var ads = getCookie("admin");
	if ( ads == "true" ) {
		return true;
	}
	else {
		return false;
	}
}


function clearAdmin () {
	deleteCookie ( "admin" );
}




function setLogin (  ) {
	var viewer = getUser();
	var embedded = getCookie("embedded");
	if ( embedded == "true" ) {
		$("#login").hide();
	}
	else {
		$("#login").show();
	}
	if ( !viewer ) {
		$(".logged-in").hide();
		$(".not-logged-in").show();
		$(".admin-view").hide();
		$(".no-admin").show();
		$("#login").html ( "<a href=\"javascript:login()\">Login</a> | <a href=\"javascript:register()\">Register</a>" );
		return false;
	}
	else {
		storedPassword = getStoredPassword();
		$(".logged-in").show();
		$(".not-logged-in").hide();
		var admin = getCookie("admin");
		if ( admin == "true" ) {
			$(".admin-view").show();
			$(".no-admin").hide();
		}
		else {
			$(".admin-view").hide();
			$(".no-admin").show();
		}
		$("#login").html ("<a href=\"javascript:logout()\">Logout</a>");
		//var userLink = '<a href="user.html">'+viewer.accountinfo.realname+'</a>';
		//$("#identity_name").html(userLink);
		
		return true;
	}
	/*if ( signedInUser == null ) {
		$("#identity").html("Not logged in:");
		$("#login_action").html ( "<a href=\"javascript:login()\">Login</a> or <a href=\"javascript:register()\">Register</a>");
		// hide any html elements with an id of "logged-in"
		$(".logged-in").hide();
		$(".not-logged-in").show();
	}
	else {
		$("#identity").html(signedInUser.accountinfo.realname);
		$("#login_action").html ("<a href=\"javascript:logout()\">Logout</a>");
		// show any html elments with an id of logged-in"
		$(".logged-in").show();
		$(".not-logged-in").hide();
	}*/
}



function updateTips(t) {
	$(".validateTips").text(t).addClass("ui-state-highlight");
	setTimeout(function() {
		$(".validateTips").removeClass("ui-state-highlight", 1500);
	}, 500);
}

function checkLength(o, n, min, max) {
	if (o.val().length > max || o.val().length < min) {
		o.addClass("ui-state-error");
		updateTips("Length of " + n + " should be between " + min + " and " + max
				+ ".");
		return false;
	} else {
		return true;
	}
}

function checkRegexp(o, regexp, n) {
	if (!(regexp.test(o.val()))) {
		o.addClass("ui-state-error");
		updateTips(n);
		return false;
	} else {
		return true;
	}
}



// modified from jQuery UI
function initRegisterDialog () {
	var username = $("#r-username");
	var email = $("#r-email");
	var password = $("#r-password");
	var realname = $("#r-realname");
	var allFields = $( [] ).add( username ).add( email ).add( password ).add(realname);
	$( "#register-form" ).dialog({
		autoOpen: false,
		height: 350,
		width: 350,
		modal: true,
		buttons: {
			"Register": function() {
				var bValid = true;
				allFields.removeClass( "ui-state-error" );


				bValid = bValid && checkLength( username, "username", 3, 16 );
				bValid = bValid && checkLength( email, "email", 6, 80 );
				bValid = bValid && checkLength( password, "password", 5, 16 );

				bValid = bValid && checkRegexp( username, /^[a-z]([0-9a-z_])+$/i, "Username may consist of a-z, 0-9, underscores, begin with a letter." );
				// From jquery.validate.js (by joern), contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/
				bValid = bValid && checkRegexp( email, /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i, "eg. ui@jquery.com" );
				bValid = bValid && checkRegexp( password, /^([0-9a-zA-Z])+$/, "Password field only allow : a-z 0-9" );

				if ( bValid ) {
					registerViaAjax ( username.val(), password.val(), email.val(), realname.val() );
					$( this ).dialog( "close" );
				}
			},
			Cancel: function() {
				$( this ).dialog( "close" );
			}
		},
		close: function() {
			allFields.val("").removeClass ( "ui-state-error");
			$(".validateTips").html("");
		}
	});
}

//modified from jQuery UI
function initLoginDialog () {
	var username = $("#l-username");
	var password = $("#l-password");
	var allFields = $([]).add(username).add(password);
	$("#login-form").dialog({
		autoOpen: false,
		height: 250,
		width: 350,
		modal: true,
		buttons: {
			"Login": function() {

				var bvalid = true;
				
				bvalid = bvalid && checkLength (username, "username", 3, 16 );
				bvalid = bvalid && checkLength (password, "password", 5, 16 );
				if ( bvalid ) {
					loginStandalone ( username.val(), password.val());
					$(this).dialog("close");
				}
			},
			Cancel: function () {
				$(this).dialog("close");
			}
		},
		close: function() {
			allFields.val("").removeClass("ui-state-error");
			$(".validateTips").html("");
		}
	});
}




// shows the login dialog
function appendFormsIfRequired ( ) {
	var check = $("#login-form");
	if ( check.length ) {
		return;
	}
	$("#page").append(dialogs);
	initRegisterDialog();
	initLoginDialog();
}


function register ( ) {
	appendFormsIfRequired();
	$("#register-form").dialog("open");
}


function login () {
	appendFormsIfRequired();
	$("#login-form").dialog("open");
}


function logout ( ) {
	// TODO - alert asking if user meant to logout
	removeUser();
	clearStoredPassword();
	setLogin();
}




function registerViaAjax ( new_username, new_password, new_email, new_realname ) {
	setStoredPassword (new_password);
	$.ajax ({
		type:"POST",
		url:store_rest_url+"/users/edit",
		data:{username:new_username, password:new_password, email:new_email, realname:new_realname},
		dataType:"text",
		success:parseIncomingUser,
		complete:registrationComplete
	});
}


function loginStandalone ( in_username, in_password ) {
	setStoredPassword ( in_password );
	$.ajax({
		type: "POST",
		url:store_rest_url+"/users/login",
		data:{username:in_username, password:in_password},
		dataType:"text",
		success: parseIncomingUser,
		complete: loginStandaloneComplete
	});	
}

function loginViaAjax ( in_username, in_password ) {
	setStoredPassword(in_password);
	$.ajax({
		type: "POST",
		url:store_rest_url+"/users/login",
		data:{username:in_username, password:in_password},
		dataType:"text",
		success: parseIncomingUser,
		complete: loginComplete
	});
}


function registrationFailed ( jqXHR, textStatus, errorThrown ) {
	alert("registration failed, reason: "+jqXHR.status );
	removeUser();
	setLogin();
}

function loginStandaloneComplete ( xhr, textStatus ) {
	switch ( xhr.status) {
	case 404:
		clearStoredPassword();
		$(".validateTips").text("Username or password not recognized");
		$("#login-form").dialog("open");
		break;
	case 200:
		break;
	default:
		alert ( "Error logging in, status: "+xhr.status);
		clearStoredPassword();
	}
}


function loginComplete ( xhr, textStatus ) {
	switch ( xhr.status) {
	case 404:
		// user doesn't exist yet so create one.
		var waveViewer = getWaveViewer();
		var displayName = waveViewer.getDisplayName();
		var id = waveViewer.getId();
		var password = "internaltemp";
		registerViaAjax (id, password, id+"@itec.org", displayName );
		break;
	case 200:
		break;
	default:
		alert ( "Error logging in, status: "+xhr.status);
		storedPassword = null;
	}
}


function registrationComplete ( xhr, textStatus ) {
	switch (xhr.status) {
	case 409:
		clearStoredPassword();
		$(".validateTips").text("Sorry that username is already taken");
		$("#register-form").dialog("open");
	case 200:
	case 201:
		break;

	default:
		alert("Error registering user, status returned: " + xhr.status);
		clearStoredPassword();
	}	
}


function loginFailed ( jqXHR, textStatus, errorThrown ) {
	alert("login failed, reason: "+textStatus+" "+errorThrown);
}

function parseIncomingUser ( userJSON ) {
	setUser(userJSON);
	var u = getUser();
	storedPassword = getStoredPassword();
	setLogin();
	//$(".logged-in").show();
	//$(".not-logged-in").hide();
	//$("#identity_name").html('<a href="user.html">'+u.accountinfo.realname+'</a>');
	sendSignal("userLoggedIn");
}


// ---------------------------------------------------------------------------------
// User permissions
// ---------------------------------------------------------------------------------


// TODO this logic needs implementing
function userCanEdit ( ) {
	var u = getUser();
	if ( u ) {
		return true;
	}
	return false;
}

// ---------------------------------------------------------------------------------
// Tag functions
// ---------------------------------------------------------------------------------


function getAllTags ( ) {
	$.ajax({
		type: "GET",
		url:store_rest_url+"/tags",
		dataType: "text",
		success: storeTags
	});
}


function getPopularTags ( ) {
	$.ajax({
		type: "GET",
		url:store_rest_url+"/tags/popular",
		dataType: "text",
		success: storePopularTags
	});
}


function addNewTag ( widget_id, tagtext ) {
	var u = getUser();
	if ( u == null ) {
		alert ( "You must be logged in to create tags!");
		return;
	}
	var uri = store_rest_url+"/tags/edit/"+widget_id;
	$.ajax({
		type: "POST",
		url: uri,
		beforeSend: function(xhr) {
			var authString = getBase64Authentication();
			xhr.setRequestHeader("Authorization", "Basic "+authString);
		},
		data: {tag: tagtext},
		dataType: "text",
		complete: tagsChangedComplete,
		success: tagsChangedAction
	});
}

function addExistingTagToWidget ( widget_id, tagText ) {
	addNewTag ( widget_id, tagText );
}


function removeTagFromWidget ( tag_id, widget_id ) {
	var uri = store_rest_url+"/tags/edit/"+widget_id+"/"+tag_id;
	var u = getUser();
	if ( u == null ) {
		alert ("You must be logged in to remove tags" );
		return;
	}
	$.ajax({
		type: "DELETE",
		beforeSend: function(xhr) {
			var authString = getBase64Authentication();
			xhr.setRequestHeader("Authorization", "Basic "+authString);
		},
		url: uri,
		//xhrFields: {
		//	withCredentials: true
		//},
		complete: removeTagResult
	});
}


function removeTagError ( xhr, errorStatus, exception ){
	alert ( "Error: "+ errorStatus + " Exception: "+xhr.readyState );
}


function removeTagResult ( xhr, textStatus ) {
	switch(xhr.status) {
	case 200:
		sendSignal("tagsChanged" );
		break;
		
	default:
		sendSignal ("tagsNotChanged", "Error trying to remove tag, status: "+textStatus);
		break;
	}
}

function tagsChangedComplete ( xhr, textStatus ) {
	switch (xhr.status) {
		case 200:
			break;
		
		default:
			alert ( "Error adding tag, status: "+xhr.statusText);
			break;
	}
}



function tagsChangedAction ( json ) {
	msg = $.parseJSON(json);
	if ( msg.message == "OK" ) {
		sendSignal ( "tagsChanged" );
	}
	else {
		sendSignal ( "tagsNotChanged", msg.message );
	}
}


function storeTags ( jsonString ) {
	tagList = $.parseJSON(jsonString);
	
}

function storePopularTags ( jsonString ) {
	popularTags = $.parseJSON(jsonString);
	for (var i=0; i<popularTags.length;i++) {
		var tag = popularTags[i][0];
		var tagHTML = '<li><a href="#" onclick="searchWidgetsForTag('+tag.id+')">'+tag.tagtext+'</a></li>';
		$("#tagsContainer").append(tagHTML);
	}
}

function findTagInArray ( tag, arr ) {
	for ( var i=0; i<arr.length; i++ ) {
		if ( arr[i].id == tag.id ) {
			return arr[i];
		}
	}
	return null;
}


function openTagsDialog ( ) {
	if ($("#tags-dialog").length == 0 ) {
		$("#page").append(tagsDialog);
	}
	var tagsHTML='';
	if ( tagList != null ) {
		var widgetTags = widget.widgetProfile.tags;
		for (var i=0; i<tagList.length;i++) {
			var tag = tagList[i];
			if ( findTagInArray(tag, widgetTags) == null) {
				tagsHTML += renderATag(tag);
			}
		}
	}
	$("#tags-dialog").html(tagsHTML);
	$("#tags-dialog").dialog();
}

function renderATag(tag) {
	var tagHTML = '<div class="tag-box" style="cursor:pointer;" onclick="chooseThisTag(\''+tag.tagtext+'\')">'+tag.tagtext+'</div>';
	return tagHTML;
}


function chooseThisTag(tagText) {
	if ( widget == null ) {
		alert ( "You must have a widget selected to tag it!");
	}
	addExistingTagToWidget ( widget.widgetProfile.id, tagText);
	$("#tags-dialog").dialog('close');
}




// ---------------------------------------------------------------------------------
// Ratings
// ---------------------------------------------------------------------------------

function getUserRatingForWidget ( ) {
	var u = getUser();
	if ( u == null ) {
		alert("Must be logged in to view your rating");
		return;
	}
	var username = u.username;
	if ( widget == null ) {
		return;
	}
	var widgetId = widget.widgetProfile.id;
	var uri = store_rest_url+"/ratings/"+widgetId;
	$.ajax ({
		type: "GET",
		beforeSend: function(xhr) {
			var authString = getBase64Authentication();
			xhr.setRequestHeader("Authorization", "Basic "+authString);
		},
		url: uri,
		dataType: "text",
		success: userRating
	});
}
function userRating ( jsonString ) {
	var r = $.parseJSON(jsonString);
	sendSignal ( "newRating", r.rating);
}


function setUserRatingForWidget ( newRating ) {
	var u = getUser();
	if ( u == null ) {
		alert ("You must be logged in to rate a widget");
		return;
	}
	var username = u.username;
	if ( widget == null ) {
		return;
	}
	var widgetId = widget.widgetProfile.id;
	$.ajax({
		type: "POST",
		url: store_rest_url+"/ratings/edit/"+widgetId+"/"+newRating,
		beforeSend: function(xhr) {
			var authString = getBase64Authentication();
			xhr.setRequestHeader("Authorization", "Basic "+authString);
		},
		dataType: "text",
		success: userRatingPosted
	});
}

function userRatingPosted (jsonString ) {
	sendSignal ( "newRating");
}




// ------------------------------------------------------------------------------------
// functionalities
// ------------------------------------------------------------------------------------

function getFunctionalities ( level ) {
	var uri = store_rest_url+"/functionalities";
	$("#functionalities_group_list").html("");
	if ( level > 0 ) {
		uri += "/"+level;
	}
	
	$.ajax({
		type: "GET",
		url: uri,
		dataType: "text",
		success: parseFunctionalities
	});
}


function parseFunctionalities ( jsonString ) {
	var functionalities = $.parseJSON ( jsonString );
	sendSignal("receivedFunctionalities", functionalities );
}


// ---------------------------------------------------------------------------------
// navigation for widget
// ---------------------------------------------------------------------------------


function buildUrl ( ){
	var id = getCookie("idKey");
	var prx = getCookie("proxyUrl");
	var url = "index.html";
	if ( id ) {
		url += "?idkey="+id;
		if ( prx ) {
			url += "&proxy="+prx;
		}
	}
	return url;
}

function goHome ( ) {

	window.location=buildUrl();
}


function searchStore ( ) {
	var search = $("#searchText").val();
	var url = buildUrl();
	if ( url.indexOf("?") != -1 ) {
		url += "&q="+search;
	}
	else {
		url += "?q="+search;
	}
	window.location=url;
}


function goToMyWidgets() {
	if ( arguments.length == 1 ) {
		window.location="user.html?widgetId="+arguments[0];
	}
	else {
		window.location="user.html";
	}
}

function goToAdmin() {
	window.location="admin.html";
}

function goToWidgetCreator() {
	window.location="upload.html";
}


function goToCategorySearch() {
	window.location="category_search.html";
}


function goToFavourites() {
	window.location="favourites.html";
}

	
function showWidgetView ( widget_id ) {
	window.location = "widget_view.html?widgetId="+widget_id;
}

// language support

//var currentLanguage = "en";

function getDisplayString ( displayStringName ) {
	var value = null;
	var currentLanguage = getCookie("language");
	if ( currentLanguage+"_"+displayStringName in window ) {
		value = eval(currentLanguage+"_"+displayStringName);
	}
	else {
		// en (English) value is default
		value = eval ("en_"+displayStringName );
	}
	return value;
}


function setLanguage ( lang ) {
	currentLanguage = lang;
}


// usage tracking functions

function incrementWidgetStats(widgetId, statType) {
	var restURI = store_rest_url + "/stats/"+statType+"/"+widgetId;
	$.ajax({
		url: restURI,
		type: "POST"
	});
}


// widget favourites
function setWidgetFavourite(widgetId)
{
	var restURI = store_rest_url + "/users/favourites/"+widgetId+"/0";
	$.ajax ({
		type: "POST",
		url:restURI,
		dataType:"text",
		beforeSend: function(xhr) {
			var authString = getBase64Authentication();
			xhr.setRequestHeader("Authorization", "Basic "+authString);
		},
		success: favouriteSet
	});
		
}


function removeWidgetFavourite(widgetId)
{
	var restURI = store_rest_url + "/users/favourites/"+widgetId;
	$.ajax ({
		type: "DELETE",
		url:restURI,
		dataType:"text",
		beforeSend: function(xhr) {
			var authString = getBase64Authentication();
			xhr.setRequestHeader("Authorization", "Basic "+authString);
		},
		success: favouriteSet
	});
}


function favouriteSet( jsonString ) {
	var favourite = $.parseJSON(jsonString);
	//alert ("Widget added to your favourites");
	
	// go to front of store with favourites
}

// -----------------------------------------------------------------
// visual and page building
// at the moment this only handles the language strings for the user
// interface.
// -----------------------------------------------------------------


// parent class for all page builders
function PageBuilder () {
	//PageBuilder.prototype.build = function () {
		// abstract
	//}
}

PageBuilder.prototype.build = function(){/*abstract*/};


// entry point for building the page
// builder is a child class based upon the above parent
function buildPage ( builder ) {
	buildNavigation ( ); // this is the same for every page
	builder.build();
}



function buildNavigation ( )
{
	$("#store_link").html(getDisplayString("widget_store_link"));
	$("#categories_link").html(getDisplayString("categories_link"));
	$("#favourites_link").html(getDisplayString("favourites_link"));
	$("#my_widgets_link").html(getDisplayString("my_widgets_link"));
	$("#creator_link").html(getDisplayString("creator_link"));
	$("admin_link").html(getDisplayString("admin_link"));
}